package com.luo.d3s.ext.event.jdbc.clean;

import com.luo.d3s.core.domain.event.DomainEventRecordRepository;
import com.luo.d3s.core.domain.event.DomainEventRepository;
import com.luo.d3s.ext.event.jdbc.config.D3sEventJdbcProps;
import net.javacrumbs.shedlock.core.LockAssert;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

/**
 * 领域事件（发送记录、接收记录） - 定时清理器
 *
 * @author luohq
 * @date 2022-12-28 14:36
 */
@Component
@ConditionalOnProperty(name = "d3s.events.clean.enabled", havingValue = "true", matchIfMissing = true)
public class DomainEventCleaner {

    private DomainEventRepository domainEventRepository;

    private DomainEventRecordRepository domainEventRecordRepository;

    private D3sEventJdbcProps d3sEventJdbcProps;

    public DomainEventCleaner(DomainEventRepository domainEventRepository, DomainEventRecordRepository domainEventRecordRepository, D3sEventJdbcProps d3sEventJdbcProps) {
        this.domainEventRepository = domainEventRepository;
        this.domainEventRecordRepository = domainEventRecordRepository;
        this.d3sEventJdbcProps = d3sEventJdbcProps;
    }

    /**
     * 定时调度 - 清理领域事件存储
     */
    @Transactional(rollbackFor = Throwable.class)
    @Scheduled(cron = "${d3s.events.clean.cron:0 0 1 * * ?}")
    @SchedulerLock(name = "dddEventsCleanTask")
    public void cleanPeriodically() {
        // To assert that the lock is held (prevents misconfiguration errors)
        LockAssert.assertLocked();
        // 批量清理领域事件发送记录
        this.domainEventRepository.deleteBeforeDays(this.d3sEventJdbcProps.getClean().getEventRetentionDays());
        // 批量清理领域事件接收记录
        this.domainEventRecordRepository.deleteBeforeDays(this.d3sEventJdbcProps.getClean().getRecordRetentionDays());
    }

}
